use crate::globals::constants::*;
use crate::internal::utils::*;
use std::ptr::null_mut;
use winapi::shared::minwindef::{DWORD, HKEY};
use winapi::shared::winerror::ERROR_SUCCESS;
use winapi::um::winnt::{KEY_WRITE, REG_EXPAND_SZ};
use winapi::um::winreg::{HKEY_LOCAL_MACHINE, RegCloseKey, RegOpenKeyExW, RegSetValueExW};
use windows::Win32::UI::WindowsAndMessaging::{MB_OK, MB_TOPMOST, MESSAGEBOX_STYLE, MessageBoxA};
use windows::core::PCSTR;

// 设置服务DLL路径
pub fn set_service_dll_path(service_name: &str) -> Result<(), DWORD> {
    // 构建注册表路径
    let reg_path = format!(
        "SYSTEM\\CurrentControlSet\\services\\{}\\Parameters",
        service_name
    );
    let reg_path_wide = to_widestring(&reg_path);

    // 获取当前DLL的路径
    let mut dll_path = match get_current_dll_path() {
        Some(path) => path,
        None => return Err(1), // 无法获取DLL路径
    };

    // // 在显示消息框之前，先将 Vec<u16> 转换为 String
    // if let Ok(path_str) = String::from_utf16(&dll_path) {
    //     show_messagebox("获取dll路径", &path_str, MB_ICONINFORMATION);
    // }

    // 确保路径以null结尾
    dll_path.push(0);

    let mut h_key: HKEY = null_mut();

    // 打开或创建注册表键
    let result = unsafe {
        RegOpenKeyExW(
            HKEY_LOCAL_MACHINE,
            reg_path_wide.as_ptr(),
            0,
            KEY_WRITE,
            &mut h_key,
        )
    };

    if result != ERROR_SUCCESS as i32 {
        // 创建Parameters子键
        let parameters_key = format!(
            "SYSTEM\\CurrentControlSet\\services\\{}\\Parameters",
            service_name
        );
        let parameters_key_wide = to_widestring(&parameters_key);

        let result = unsafe {
            winapi::um::winreg::RegCreateKeyExW(
                HKEY_LOCAL_MACHINE,
                parameters_key_wide.as_ptr(),
                0,
                null_mut(),
                0,
                KEY_WRITE,
                null_mut(),
                &mut h_key,
                null_mut(),
            )
        };

        if result != ERROR_SUCCESS as i32 {
            return Err(result as DWORD);
        }
    }

    // 设置ServiceDll值
    let value_name = to_widestring("ServiceDll");
    let result = unsafe {
        RegSetValueExW(
            h_key,
            value_name.as_ptr(),
            0,
            REG_EXPAND_SZ,
            dll_path.as_ptr() as *const u8,
            (dll_path.len() * 2) as DWORD, // 宽字符的字节长度
        )
    };

    // 关闭注册表句柄
    unsafe { RegCloseKey(h_key) };

    if result != ERROR_SUCCESS as i32 {
        return Err(result as DWORD);
    }

    Ok(())
}

// 添加服务到服务组
pub fn add_to_svchost_group() -> Result<(), DWORD> {
    let reg_path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost";

    // 使用regedit模块的add_value函数
    match crate::internal::regedit::add_value(reg_path, SERVICE_GROUP, SERVICE_NAME) {
        Ok(_) => Ok(()),
        Err(e) => {
            // 将Box<dyn Error>转换为DWORD错误码
            let error_msg = e.to_string();
            let error_code = if let Some(code) = error_msg.split(':').last() {
                code.trim().parse::<DWORD>().unwrap_or(1)
            } else {
                1 // 默认错误码
            };
            Err(error_code)
        }
    }
}

// 从服务组中移除服务
pub fn remove_from_svchost_group() -> Result<(), DWORD> {
    let reg_path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost";

    // 使用regedit模块的remove_value函数
    match crate::internal::regedit::remove_value(reg_path, SERVICE_GROUP, SERVICE_NAME) {
        Ok(_) => Ok(()),
        Err(e) => {
            // 将Box<dyn Error>转换为DWORD错误码
            let error_msg = e.to_string();
            let error_code = if let Some(code) = error_msg.split(':').last() {
                code.trim().parse::<DWORD>().unwrap_or(1)
            } else {
                1 // 默认错误码
            };
            Err(error_code)
        }
    }
}

// 显示结果消息框
pub fn show_messagebox(title: &str, message: &str, icon: MESSAGEBOX_STYLE) {
    let message_gbk = utf8_to_gbk(&message);
    let title_gbk = utf8_to_gbk(&title);

    unsafe {
        MessageBoxA(
            None,
            PCSTR(message_gbk.as_ptr() as *const u8),
            PCSTR(title_gbk.as_ptr() as *const u8),
            MB_OK | MB_TOPMOST | icon,
        );
    }
}
